using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using System.Threading;
using Utilities;

namespace XNAGame
{
  public class MenuItem
  {
    public string Name { get; set; }
    public Action<MenuComponent, Microsoft.Xna.Framework.Game> Action { get; set; }
  }

  public class MenuComponent : Microsoft.Xna.Framework.DrawableGameComponent
  {
    SpriteBatch spriteBatch;
    MenuItem[] items;
    int current_item = 0;

    public MenuComponent(Game game, ArrayList<MenuItem> items)
      : base(game)
    {
      this.items = items.ToArray();
    }

    ContentManager Content { get { return Game.Content; } }

    protected override void LoadContent()
    {
      spriteBatch = new SpriteBatch(Game.GraphicsDevice);
      
      base.LoadContent();
    }

    GamePadState gps = GamePad.GetState(PlayerIndex.One);
    KeyboardState kbs = Keyboard.GetState();
    bool performing_action = true;
    public override void Initialize()
    {
      new Thread(() =>
        {
          while (running)
          {
            if (kbs.IsKeyDown(Keys.Q) || gps.IsButtonDown(Buttons.Back))
              Game.Exit();

            if (performing_action == false && (kbs.IsKeyDown(Keys.Enter) || gps.IsButtonDown(Buttons.A)))
            {
              performing_action = true;
              items[current_item].Action(this, this.Game);
              Thread.Sleep(50);
            }
            else
            {
              performing_action = false;
            }

            if (gps.ThumbSticks.Left.Y >= 0.5f || gps.ThumbSticks.Right.Y >= 0.5f ||
                kbs.IsKeyDown(Keys.Up))
            {
              current_item = (current_item - 1 + items.Length) % items.Length;
              Thread.Sleep(200);
            }

            if (gps.ThumbSticks.Left.Y <= -0.5f || gps.ThumbSticks.Right.Y <= -0.5f ||
                kbs.IsKeyDown(Keys.Down))
            {
              current_item = (current_item + 1) % items.Length;
              Thread.Sleep(200);
            }
            Thread.Sleep(30);
          }
        }).Start();

      base.Initialize();
    }

    bool running = true;
    protected override void Dispose(bool disposing)
    {
      running = false;
      Thread.Sleep(0);
      base.Dispose(disposing);
    }

    public override void Update(GameTime gameTime)
    {
      gps = GamePad.GetState(PlayerIndex.One);
      kbs = Keyboard.GetState();

      base.Update(gameTime);
    }

    public override void Draw(GameTime gameTime)
    {
      GraphicsDevice.Clear(Color.CornflowerBlue);

      var menuFont = Content.Load<SpriteFont>(@"fonts\arial18ptx");

      spriteBatch.Begin();

      var y_offset = (float)GraphicsDevice.Viewport.Height / 40;
      for (int i = 0; i < items.Length; i++)
      {
        var s = menuFont.MeasureString(items[i].Name);
        var color = i == current_item ? Color.Yellow : Color.White;
        spriteBatch.DrawString(menuFont, items[i].Name,
          new Vector2(GraphicsDevice.Viewport.Width / 2 - s.X / 2, y_offset), color);
        y_offset += s.Y + GraphicsDevice.Viewport.Height / 80;
      }

      spriteBatch.End();

      base.Draw(gameTime);
    }
  }
}